package com.wmx.spring;

import cn.hutool.core.util.ArrayUtil;
import org.junit.Test;
import org.springframework.web.util.UriUtils;

import java.nio.charset.Charset;

/**
 * Springframework UriUtils 是基于 RFC3986 的 URI 编码和解码实用工具类。
 * <p>
 * 1、encodeXyz 编码方法：它们对特定 URI 组件(例如路径、查询参数)进行百分比编码，对非法字符进行编码，其中包括非 US-ASCII 字符，以及在给定 URI 中非法的字符
 * URI组件类型，如RFC 3986中定义的。此方法在编码方面的效果与使用多参数构造函数相当。
 * 2、encode 和 encodeUriVariables 编码方法：可以通过对 URI 中任何位置的非法字符或具有任何保留含义的字符进行百分比编码来对URI变量值进行编码。
 *
 * @author wangMaoXiong
 * @version 1.0
 * @date 2021/12/8 9:04
 */
public class UriUtilsTest {
    /**
     * 解码给定的编码URI组件。当给定源包含无效的编码序列时引发IllegalArgumentException
     * String decode(String source, Charset charset)
     * String decode(String source, String encoding)
     * * source：许解码的字符串,未编码的字符串解码时不受影响
     * * charset、encoding：要使用的字符编码
     * * 返回解码后的值
     */

    /**
     * 对整个 URI 的非法字符或具有任何保留含义的字符进行编码,这有助于确保给定字符串保持原样，并且不会对URI的结构或含义产生任何影响。
     * String encode(String source, Charset charset)
     * String encode(String source, String encoding)
     * * source：要编码的字符串
     * * charset、encoding：要编码的字符编码
     * * 返回编码字符串
     */
    @Test
    public void testEncode() {
        String sourceUri = "https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004";

        String encode1 = UriUtils.encode(sourceUri, Charset.forName("UTF-8"));
        String encode2 = UriUtils.encode(sourceUri, Charset.forName("gbk"));

        //https%3A%2F%2Fwww.baidu.com%2Fbaidu%3Ftn%3Dmonline_3_dg%26ie%3Dutf-8%26wd%3D%E5%86%AC%E5%A5%A5%E4%BC%9A%26wf_state%3D001%7C004
        System.out.println(encode1);
        //https%3A%2F%2Fwww.baidu.com%2Fbaidu%3Ftn%3Dmonline_3_dg%26ie%3Dutf-8%26wd%3D%B6%AC%B0%C2%BB%E1%26wf_state%3D001%7C004
        System.out.println(encode2);

        String decode1 = UriUtils.decode(encode1, Charset.forName("UTF-8"));
        String decode2 = UriUtils.decode(encode2, Charset.forName("gbk"));

        //https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004
        System.out.println(decode1);
        //https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004
        System.out.println(decode2);

        String decode4 = UriUtils.decode(sourceUri, "UTF-8");
        //https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004
        System.out.println(decode4);
    }

    /**
     * 使用给定的编码对给定的URI权限进行编码。
     * String encodeAuthority(String authority, Charset charset)
     * String encodeAuthority(String authority, String encoding)
     * * authority：要编码的权限
     * * charset：要编码的字符编码
     * * 返回已编码的权限
     */
    @Test
    public void testEncodeAuthority() {
        String sourceUri = "https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004";

        String encode1 = UriUtils.encodeAuthority(sourceUri, Charset.forName("UTF-8"));
        String encode2 = UriUtils.encodeAuthority(sourceUri, Charset.forName("gbk"));

        //encode1=https:%2F%2Fwww.baidu.com%2Fbaidu%3Ftn=monline_3_dg&ie=utf-8&wd=%E5%86%AC%E5%A5%A5%E4%BC%9A&wf_state=001%7C004
        System.out.println("encode1=" + encode1);
        //encode2=https:%2F%2Fwww.baidu.com%2Fbaidu%3Ftn=monline_3_dg&ie=utf-8&wd=%B6%AC%B0%C2%BB%E1&wf_state=001%7C004
        System.out.println("encode2=" + encode2);

        String decode1 = UriUtils.decode(encode1, "UTF-8");
        String decode2 = UriUtils.decode(encode2, "gbk");

        //decode1=https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004
        System.out.println("decode1=" + decode1);
        //decode2=https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004
        System.out.println("decode2=" + decode2);
    }

    /**
     * 使用给定的编码对给定的 URI 片段进行编码。
     * String encodeFragment(String fragment, Charset charset)
     * String encodeFragment(String fragment, String encoding)
     */
    @Test
    public void testEncodeFragment() {
        String sourceUri = "https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004";

        String encode1 = UriUtils.encodeFragment(sourceUri, Charset.forName("UTF-8"));
        String encode2 = UriUtils.encodeFragment(sourceUri, Charset.forName("gbk"));

        //encode1=http://10.104.41.8:28002/baidu?tn=monline_3_dg&ie=utf-8&wd=%E5%86%AC%E5%A5%A5%E4%BC%9A&wf_state=001%7C004
        System.out.println("encode1=" + encode1);
        //encode2=http://10.104.41.8:28002/baidu?tn=monline_3_dg&ie=utf-8&wd=%B6%AC%B0%C2%BB%E1&wf_state=001%7C004
        System.out.println("encode2=" + encode2);

        String decode1 = UriUtils.decode(encode1, Charset.forName("UTF-8"));
        String decode2 = UriUtils.decode(encode2, Charset.forName("gbk"));

        //decode1=http://10.104.41.8:28002/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004
        System.out.println("decode1=" + decode1);
        //decode2=http://10.104.41.8:28002/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004
        System.out.println("decode2=" + decode2);
    }


    /**
     * 使用给定的编码对给定的URI主机进行编码。
     * String encodeHost(String host, Charset charset)
     * String encodeHost(String host, String encoding)
     */
    @Test
    @SuppressWarnings("all")
    public void testEncodeHost() {
        String sourceUri = "https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004";

        String encodeHost1 = UriUtils.encodeHost(sourceUri, Charset.forName("UTF-8"));
        String encodeHost2 = UriUtils.encodeHost(sourceUri, Charset.forName("gbk"));

        //https%3A%2F%2Fwww.baidu.com%2Fbaidu%3Ftn=monline_3_dg&ie=utf-8&wd=%E5%86%AC%E5%A5%A5%E4%BC%9A&wf_state=001%7C004
        System.out.println("encodeHost1=" + encodeHost1);
        //https%3A%2F%2Fwww.baidu.com%2Fbaidu%3Ftn=monline_3_dg&ie=utf-8&wd=%B6%AC%B0%C2%BB%E1&wf_state=001%7C004
        System.out.println("encodeHost2=" + encodeHost2);

        String decodeHost1 = UriUtils.decode(encodeHost1, Charset.forName("UTF-8"));
        String decodeHost2 = UriUtils.decode(encodeHost2, Charset.forName("gbk"));

        //https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004
        System.out.println("decodeHost1=" + decodeHost1);
        //https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004
        System.out.println("decodeHost2=" + decodeHost2);
    }

    /**
     * 使用给定的编码对给定的URI路径进行编码。
     * String encodePath(String path, Charset charset)
     * String encodePath(String path, String encoding)
     */
    @Test
    @SuppressWarnings("all")
    public void testEncodePath() {
        String sourceUri = "https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004";

        String encodeHost1 = UriUtils.encodePath(sourceUri, Charset.forName("UTF-8"));
        String encodeHost2 = UriUtils.encodePath(sourceUri, Charset.forName("gbk"));

        //https://www.baidu.com/baidu%3Ftn=monline_3_dg&ie=utf-8&wd=%E5%86%AC%E5%A5%A5%E4%BC%9A&wf_state=001%7C004
        System.out.println("encodeHost1=" + encodeHost1);
        //https://www.baidu.com/baidu%3Ftn=monline_3_dg&ie=utf-8&wd=%B6%AC%B0%C2%BB%E1&wf_state=001%7C004
        System.out.println("encodeHost2=" + encodeHost2);

        String decodeHost1 = UriUtils.decode(encodeHost1, Charset.forName("UTF-8"));
        String decodeHost2 = UriUtils.decode(encodeHost2, Charset.forName("gbk"));

        //https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004
        System.out.println("decodeHost1=" + decodeHost1);
        System.out.println("decodeHost2=" + decodeHost2);
    }

    /**
     * 使用给定的编码对给定的URI路径段进行编码
     * String encodePathSegment(String segment, Charset charset)
     * String encodePathSegment(String segment, String encoding)
     */
    @Test
    @SuppressWarnings("all")
    public void testEncodePathSegment() {
        String sourceUri = "https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004";

        String encodeHost1 = UriUtils.encodePathSegment(sourceUri, Charset.forName("UTF-8"));
        String encodeHost2 = UriUtils.encodePathSegment(sourceUri, Charset.forName("gbk"));

        //https:%2F%2Fwww.baidu.com%2Fbaidu%3Ftn=monline_3_dg&ie=utf-8&wd=%E5%86%AC%E5%A5%A5%E4%BC%9A&wf_state=001%7C004
        System.out.println("encodeHost1=" + encodeHost1);
        //https:%2F%2Fwww.baidu.com%2Fbaidu%3Ftn=monline_3_dg&ie=utf-8&wd=%B6%AC%B0%C2%BB%E1&wf_state=001%7C004
        System.out.println("encodeHost2=" + encodeHost2);

        String decodeHost1 = UriUtils.decode(encodeHost1, Charset.forName("UTF-8"));
        String decodeHost2 = UriUtils.decode(encodeHost2, Charset.forName("gbk"));

        //https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004
        System.out.println("decodeHost1=" + decodeHost1);
        System.out.println("decodeHost2=" + decodeHost2);
    }

    /**
     * 使用给定的编码对给定的URI端口进行编码
     * String encodePort(String port, String encoding)
     * String encodePort(String port, Charset charset)
     */
    @Test
    @SuppressWarnings("all")
    public void testEncodePort() {
        String sourceUri = "https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004";

        String encodeHost1 = UriUtils.encodePort(sourceUri, Charset.forName("UTF-8"));
        String encodeHost2 = UriUtils.encodePort(sourceUri, Charset.forName("gbk"));

        //%68%74%74%70%73%3A%2F%2F%77%77%77%2E%62%61%69%64%75%2E%63%6F%6D%2F%62%61%69%64%75%3F%74%6E%3D%6D%6F%6E%6C%69%6E%65%5F3%5F%64%67%26%69%65%3D%75%74%66%2D8%26%77%64%3D%E5%86%AC%E5%A5%A5%E4%BC%9A%26%77%66%5F%73%74%61%74%65%3D001%7C004
        System.out.println("encodeHost1=" + encodeHost1);
        //%68%74%74%70%73%3A%2F%2F%77%77%77%2E%62%61%69%64%75%2E%63%6F%6D%2F%62%61%69%64%75%3F%74%6E%3D%6D%6F%6E%6C%69%6E%65%5F3%5F%64%67%26%69%65%3D%75%74%66%2D8%26%77%64%3D%B6%AC%B0%C2%BB%E1%26%77%66%5F%73%74%61%74%65%3D001%7C004
        System.out.println("encodeHost2=" + encodeHost2);

        String decodeHost1 = UriUtils.decode(encodeHost1, Charset.forName("UTF-8"));
        String decodeHost2 = UriUtils.decode(encodeHost2, Charset.forName("gbk"));

        //https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004
        System.out.println("decodeHost1=" + decodeHost1);
        System.out.println("decodeHost2=" + decodeHost2);
    }

    /**
     * 使用给定的编码对给定的URI查询参数值进行编码(不包括等于符号)
     * String encodeQuery(String query, Charset charset)
     * String encodeQuery(String query, String encoding)
     */
    @Test
    @SuppressWarnings("all")
    public void testEncodeQuery() {
        String sourceUri = "https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004";

        String encodeHost1 = UriUtils.encodeQuery(sourceUri, Charset.forName("UTF-8"));
        String encodeHost2 = UriUtils.encodeQuery(sourceUri, Charset.forName("gbk"));

        //https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=%E5%86%AC%E5%A5%A5%E4%BC%9A&wf_state=001%7C004
        System.out.println("encodeHost1=" + encodeHost1);
        //https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=%B6%AC%B0%C2%BB%E1&wf_state=001%7C004
        System.out.println("encodeHost2=" + encodeHost2);

        String decodeHost1 = UriUtils.decode(encodeHost1, Charset.forName("UTF-8"));
        String decodeHost2 = UriUtils.decode(encodeHost2, Charset.forName("gbk"));

        //https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004
        System.out.println("decodeHost1=" + decodeHost1);
        System.out.println("decodeHost2=" + decodeHost2);
    }

    /**
     * 使用给定的编码对给定的URI查询参数进行编码(包括等于符号)
     * String encodeQueryParam(String queryParam, Charset charset)
     * String encodeQueryParam(String queryParam, String encoding)
     */
    @Test
    @SuppressWarnings("all")
    public void testEncodeQueryParam() {
        String sourceUri = "https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004";

        String encodeHost1 = UriUtils.encodeQueryParam(sourceUri, Charset.forName("UTF-8"));
        String encodeHost2 = UriUtils.encodeQueryParam(sourceUri, Charset.forName("gbk"));

        //https://www.baidu.com/baidu?tn%3Dmonline_3_dg%26ie%3Dutf-8%26wd%3D%E5%86%AC%E5%A5%A5%E4%BC%9A%26wf_state%3D001%7C004
        System.out.println("encodeHost1=" + encodeHost1);
        //https://www.baidu.com/baidu?tn%3Dmonline_3_dg%26ie%3Dutf-8%26wd%3D%B6%AC%B0%C2%BB%E1%26wf_state%3D001%7C004
        System.out.println("encodeHost2=" + encodeHost2);

        String decodeHost1 = UriUtils.decode(encodeHost1, Charset.forName("UTF-8"));
        String decodeHost2 = UriUtils.decode(encodeHost2, Charset.forName("gbk"));

        //https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004
        System.out.println("decodeHost1=" + decodeHost1);
        System.out.println("decodeHost2=" + decodeHost2);
    }

    @Test
    @SuppressWarnings("all")
    public void testEncodeScheme() {
        String sourceUri = "https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004";

        String encodeScheme = UriUtils.encodeScheme(sourceUri, Charset.forName("UTF-8"));
        String encodeUserInfo = UriUtils.encodeUserInfo(sourceUri, Charset.forName("UTF-8"));

        //https%3A%2F%2Fwww.baidu.com%2Fbaidu%3Ftn%3Dmonline%5F3%5Fdg%26ie%3Dutf-8%26wd%3D%E5%86%AC%E5%A5%A5%E4%BC%9A%26wf%5Fstate%3D001%7C004
        System.out.println("encodeScheme=" + encodeScheme);
        //https%3A%2F%2Fwww.baidu.com%2Fbaidu%3Ftn%3Dmonline%5F3%5Fdg%26ie%3Dutf-8%26wd%3D%B6%AC%B0%C2%BB%E1%26wf%5Fstate
        System.out.println("encodeUserInfo=" + ArrayUtil.toString(encodeUserInfo));

        //https://www.baidu.com/baidu?tn=monline_3_dg&ie=utf-8&wd=冬奥会&wf_state=001|004
        System.out.println(UriUtils.decode(encodeScheme, Charset.forName("UTF-8")));
        System.out.println(UriUtils.decode(encodeUserInfo, Charset.forName("UTF-8")));
    }

    /**
     * 从给定的URI路径提取文件扩展名，解析不到时，返回 null。
     * String extractFileExtension(String path)
     */
    @Test
    public void testExtractFileExtension() {
        String sourceUri1 = "https://d.ifengimg.com/w175_h98_q90/x0.ifengimg.com/ucms/2021_47/A9BD37486_size318_w1920_h1080.jpg";
        String sourceUri2 = "https://x0.ifengimg.com/feprod/c/a_if/190312/weicc/testv1.html?fsize=14px";

        String fileExtension1 = UriUtils.extractFileExtension(sourceUri1);
        String fileExtension2 = UriUtils.extractFileExtension(sourceUri2);
        //jpg
        System.out.println(fileExtension1);
        //html
        System.out.println(fileExtension2);
    }


}
